package com.caifu.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;

import com.caifu.bean.ResultUtil;
import com.caifu.mapper.SysLogMapper;
import com.caifu.mapper.UtilMapper;
import com.caifu.pojo.SysLog;
import com.caifu.util.OrgTypeSort;
import com.caifu.util.QRCodeUtils;
import com.caifu.util.Util;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.caifu.bean.Result;
import com.caifu.mapper.SysOrganizationMapper;
import com.caifu.mapper.SysUserMapper;
import com.caifu.pojo.SysOrganization;
import com.caifu.pojo.SysUser;
import com.caifu.service.SysOrganizationService;
import com.caifu.util.OrgSort;

import javax.annotation.Resource;

/**
 * <p>
 * 平台组织表 服务实现类
 * </p>
 *
 * @author szt
 * @since 2020-08-05
 */
@Service
public class SysOrganizationServiceImpl extends ServiceImpl<SysOrganizationMapper, SysOrganization> implements SysOrganizationService {

	@Resource
	private SysOrganizationMapper orgMapper;
	@Resource
	private SysUserMapper userMapper;
	@Resource
	private SysLogMapper logMapper;
	@Resource
	private UtilMapper utilMapper;

	@Value("${delivery_food_url}")
	private String deliveryFoodUrl;
	
	@Override
	public List<Map<String,Object>> listSysOrganization(String orgLevel, String parentOrgId) throws Exception{
		List<Map<String, Object>> list;
		try {
			QueryWrapper<SysOrganization> wp = new QueryWrapper<>();
			wp.eq("state", "1");
			if(StringUtils.isNotBlank(orgLevel)) {
				wp.eq("org_level", orgLevel);	
			}
			if(StringUtils.isNotBlank(parentOrgId)) {
				wp.eq("parent_org_id", parentOrgId);	
			}
			list = orgMapper.selectMaps(wp);
			for (Map<String, Object> map : list) {
				QueryWrapper<SysOrganization> twp = new QueryWrapper<>();
				twp.eq("state", "1");
				twp.eq("parent_org_id", map.get("org_id"));	
				int count = orgMapper.selectCount(twp);
				map.put("count", count);
			}
			return list;
		} catch (Exception e) {
			throw new Exception(e.toString());
		}

		
	}

	@Transactional
	@Override
	public Result<Object> deleteSysOrganization(String orgId, Integer userNo) throws Exception {
		Result<Object> rst = new Result<>();
		SysUser user = new SysUser();
		try {
			user = userMapper.selectOne(new QueryWrapper<SysUser>().eq("user_no", userNo));
			if(user==null){
				throw new Exception("在SysUser表中找不到用户信息");
			}

			QueryWrapper<SysUser> getUserWp = new QueryWrapper<>();
			getUserWp.eq("status", "1");
			getUserWp.like("org_id", orgId);
			int cnt = userMapper.selectCount(getUserWp);
			if(cnt>0) {
				//组织绑定操作人员时，不能删除
				//日志记录  sys 组织架构模块  sys-101 组织架构修改
				SysLog log = new SysLog(userNo, "1","sys", "sys-101", "9", "此行政机构下已存在操作人员, "+user.getLoginName()+"修改组织架构失败[orgId="+orgId+"]！", new Date());
				return ResultUtil.retLog(201,"此行政机构下已存在操作人员！",log);
			}

			QueryWrapper<SysOrganization> countWp = new QueryWrapper<>();
			countWp.eq("state", "1");
			countWp.eq("parent_org_id", orgId);	
			int count = orgMapper.selectCount(countWp);
			if(count>0) {
				//组织下有下级数据，不能删除
				//日志记录  sys 组织架构模块  sys-102 组织架构删除
				SysLog log = new SysLog(userNo, "1","sys", "sys-102", "1", "此组织下有下级组织, "+user.getLoginName()+"删除组织架构失败[orgId="+orgId+"]！", new Date());
				return ResultUtil.retLog(201,"此组织下有下级组织, 不能删除！",log);
			}
			
			QueryWrapper<SysOrganization> getWp = new QueryWrapper<>();
			getWp.eq("state", "1");
			getWp.eq("org_id", orgId);
			SysOrganization org = orgMapper.selectOne(getWp);

			if("4".equals(org.getType())){		//养老机构
				int elderCount = utilMapper.getElderCountByOrgId(org.getOrgId()+"");
				if(elderCount>0){
					//组织下有老人数据，不能删除
					//日志记录  sys 组织架构模块  sys-102 组织架构删除
					SysLog log = new SysLog(userNo, "1","sys", "sys-102", "1", "此组织下有老人数据, "+user.getLoginName()+"删除组织架构失败[orgId="+orgId+"]！", new Date());
					return ResultUtil.retLog(201,"此组织下有老人数据, 不能删除！",log);
				}
			}else if("3".equals(org.getType())){  //村/社区
				int userCount = utilMapper.getUserCountByOrgId(org.getOrgId()+"");
				if(userCount>0){
					//组织下有用户数据，不能删除
					//日志记录  sys 组织架构模块  sys-102 组织架构删除
					SysLog log = new SysLog(userNo, "1","sys", "sys-102", "1", "此组织下有用户数据, "+user.getLoginName()+"删除组织架构失败[orgId="+orgId+"]！", new Date());
					return ResultUtil.retLog(201,"此组织下有用户数据, 不能删除！",log);
				}
			}

			if(org!=null) {
				org.setState("9");
				orgMapper.updateById(org);
			}
			
			//判断父组织是否还存在子组织，不存在时，将isChildExist改为0
			JSONObject json = new JSONObject();
			QueryWrapper<SysOrganization> countParentWp = new QueryWrapper<>();
			countParentWp.eq("state", "1");
			countParentWp.eq("parent_org_id", org.getParentOrgId());	
			int parentCount = orgMapper.selectCount(countParentWp);
			if(parentCount==0) {
				QueryWrapper<SysOrganization> getParentWp = new QueryWrapper<>();
				getParentWp.eq("state", "1");
				getParentWp.eq("org_id", org.getParentOrgId());
				SysOrganization parentOrg = orgMapper.selectOne(getParentWp);
				if(parentOrg!=null) {
					parentOrg.setIsChildExist("0");
					orgMapper.updateById(parentOrg);
				}
				
				json.put("parentOrgId", org.getParentOrgId());				
				json.put("isParentChildExist", "0");
			}else {
				json.put("isParentChildExist", "1");
			}
			json.put("orgId", orgId);				
			rst.setData(json);

			//日志记录  sys 组织架构模块  sys-102 组织架构删除
			SysLog log = new SysLog(userNo, "1","sys", "sys-102", "1", user.getLoginName()+"删除组织架构成功[orgId="+orgId+"]！", new Date());
			logMapper.insert(log);
			return ResultUtil.success(200,"删除成功！",json);
		} catch (Exception e) {
			e.printStackTrace();
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();     
			throw new Exception(e.toString());
		}
	}

	@Override
	public net.sf.json.JSONObject getAllOrganization(String orgId) throws Exception {
		try {
			if (Util.isNull(orgId)) {
				orgId = "10";
			}
			List<Map<String,Object>> list = orgMapper.getAllOrganization(orgId);
			net.sf.json.JSONArray json = net.sf.json.JSONArray.fromObject(list);
			net.sf.json.JSONObject jo =  new net.sf.json.JSONObject();
			OrgSort.getJsontree(json,jo,orgId);
			return jo;
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception(e.toString());
		}
	}
	
	@Override
	public net.sf.json.JSONObject getAllAuthOrganization(String userNo,String orgId) throws Exception {
		try {
  			List<Map<String,Object>> list = orgMapper.getAllAuthOrganization("10", userNo);
			net.sf.json.JSONArray json = net.sf.json.JSONArray.fromObject(list);
			net.sf.json.JSONObject jo =  new net.sf.json.JSONObject();
			OrgSort.getJsontree(json,jo,Util.isNull(orgId)?"10":orgId);
			return jo;
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception(e.toString());
		}
	}

	@Override
	public net.sf.json.JSONObject getGongcanAllAuthOrganization(String userNo,String orgId) throws Exception {
		try {
			List<Map<String,Object>> list = orgMapper.getGongcanAllAuthOrganization("10", userNo);
			net.sf.json.JSONArray json = net.sf.json.JSONArray.fromObject(list);
			net.sf.json.JSONObject jo =  new net.sf.json.JSONObject();
			OrgSort.getJsontree(json,jo,Util.isNull(orgId)?"10":orgId);
			return jo;
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception(e.toString());
		}
	}

	@Override
	public net.sf.json.JSONObject getAllAuthTypeOrganization(String userNo,String type) throws Exception {
		try {
			List<Map<String,Object>> list = orgMapper.getAllAuthOrganization("10", userNo);
			String selectOrgStr = OrgTypeSort.arrDisitinct(orgMapper.getAllOrgTypePathCode(userNo, type));
			net.sf.json.JSONArray json = net.sf.json.JSONArray.fromObject(list);
			net.sf.json.JSONObject jo =  new net.sf.json.JSONObject();
			OrgTypeSort.getJsontree(json,jo,Util.null2EmptyTrim(selectOrgStr));
			return jo;
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception(e.toString());
		}
	}

	@Override
	public Result<Object> getSysOrganization(String orgId) throws Exception {
		Result<Object> rst = new Result<>();
		try {
			QueryWrapper<SysOrganization> getWp = new QueryWrapper<>();
			getWp.eq("state", "1");
			getWp.eq("org_id", orgId);
			SysOrganization org = orgMapper.selectOne(getWp);
			if(org!=null) {
				QueryWrapper<SysOrganization> getParentWp = new QueryWrapper<>();
				getParentWp.eq("state", "1");
				getParentWp.eq("org_id", org.getParentOrgId());
				SysOrganization parentOrg = orgMapper.selectOne(getParentWp);
				if(parentOrg!=null) {
					rst.setData(org);
					rst.setCode(200);
					rst.setMsg(parentOrg.getOrgName());
				}	
			}
			return rst;
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception(e.toString());
		}
	}

	@Transactional
	@Override
	public Result<Object> addSysOrganization(SysOrganization org, int userNo) throws Exception {
		Result<Object> rst = new Result<>();
		SysUser user = new SysUser();
		try {
			user = userMapper.selectOne(new QueryWrapper<SysUser>().eq("user_no", userNo));
			if(user==null){
				throw new Exception("在SysUser表中找不到用户信息");
			}

			QueryWrapper<SysOrganization> getParentWp = new QueryWrapper<>();
			getParentWp.eq("state", "1");
			getParentWp.eq("org_id", org.getParentOrgId());
			SysOrganization parentOrg = orgMapper.selectOne(getParentWp);
			if(parentOrg!=null) {
				parentOrg.setIsChildExist("1");
				orgMapper.updateById(parentOrg);
				
				String level = parentOrg.getOrgLevel();
				String curLevel = Long.parseLong(level)+1+"";
				org.setIsChildExist("0");
				org.setState("1");
				org.setRank(0l);
				org.setIsAdminInstitute("0");
				org.setOrgLevel(curLevel);
				org.setCreateBy((long)userNo);
				org.setCreateTime(new Date());
				org.setUpdateBy((long)userNo);
				org.setUpdateTime(new Date());
				orgMapper.insert(org);

				//生成机构组织路径
				org.setOrgPath(orgMapper.getOrgPath(org.getOrgId()));
				org.setOrgPathCode(orgMapper.getOrgPathCode(org.getOrgId()));
				//生成二维码
				org.setQrCode(QRCodeUtils.encodeImage(deliveryFoodUrl + "foodConfirm/index?orgId="+String.valueOf(org.getOrgId()),"organization"));
				orgMapper.updateById(org);

				//日志记录  sys 组织架构模块  sys-100 组织架构添加
				SysLog log = new SysLog(userNo, "1","sys", "sys-100", "1", user.getLoginName()+"新增组织架构成功[orgId="+org.getOrgId()+"]！", new Date());
				return ResultUtil.retLog(200,"添加成功！",log);
			}else {
				throw new Exception("组织架构添加失败！");
			}

		} catch (Exception e) {
			e.printStackTrace();
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			//日志记录  sys 组织架构模块  sys-100 组织架构添加
			SysLog log = new SysLog(userNo, "1","sys", "sys-100", "9", user.getLoginName()+"新增组织架构失败！", new Date());
			return ResultUtil.retLog(201,"添加失败！",log);
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateQr() {
		try{
			List<SysOrganization> list = orgMapper.selectList(new QueryWrapper<SysOrganization>());
			if(list != null && list.size() > 0){
				for(SysOrganization o : list){
					o.setQrCode(QRCodeUtils.encodeImage(deliveryFoodUrl + "foodConfirm/index?orgId="+String.valueOf(o.getOrgId()),"organization"));
					orgMapper.updateById(o);
				}
			}
		}catch (Exception e){
			e.printStackTrace();
		}
	}

	@Transactional
	@Override
	public Result<Object> updateSysOrganization(SysOrganization org, int userNo) throws Exception {
		Result<Object> rst = new Result<>();
		SysUser user = new SysUser();
		try {
			user = userMapper.selectOne(new QueryWrapper<SysUser>().eq("user_no", userNo));
			if(user==null){
				throw new Exception("在SysUser表中找不到用户信息");
			}

			QueryWrapper<SysOrganization> getOrgWp = new QueryWrapper<>();
			getOrgWp.eq("state", "1");
			getOrgWp.eq("org_id", org.getOrgId());
			SysOrganization oldOrg = orgMapper.selectOne(getOrgWp);
			if(oldOrg==null) {
				throw new Exception("updateSysOrganization->orgMapper.selectOne 查询失败");
			}
			//先保存老的父级组织机构代码
			long oldOrgParentId = oldOrg.getParentOrgId();

			//判断修改组织是否有老人数据，居民数据
			if(!oldOrg.getType().equals(org.getType())
					||!oldOrg.getParentOrgId().equals(org.getParentOrgId())
					||!oldOrg.getOrgName().equals(org.getOrgName())
					||!oldOrg.getOrgAddress().equals(org.getOrgAddress())){
				if("4".equals(oldOrg.getType())){		//养老机构
					int elderCount = utilMapper.getElderCountByOrgId(oldOrg.getOrgId()+"");
					if(elderCount>0){
						//组织下有老人数据，不能移动
						//日志记录  sys 组织架构模块  sys-102 组织架构删除
						SysLog log = new SysLog(userNo, "1","sys", "sys-102", "1", "此组织下有老人数据, "+user.getLoginName()+"更改组织架构失败[orgId="+oldOrg.getOrgId()+"]！", new Date());
						return ResultUtil.retLog(201,"此组织下有老人数据, 不能更改数据！",log);
					}
				}else if("3".equals(oldOrg.getType())){  //村/社区
					int userCount = utilMapper.getUserCountByOrgId(oldOrg.getOrgId()+"");
					if(userCount>0){
						//组织下有用户数据，不能删除
						//日志记录  sys 组织架构模块  sys-102 组织架构删除
						SysLog log = new SysLog(userNo, "1","sys", "sys-102", "1", "此组织下有用户数据, "+user.getLoginName()+"更改组织架构失败[orgId="+oldOrg.getOrgId()+"]！", new Date());
						return ResultUtil.retLog(201,"此组织下有用户数据, 不能更改数据！",log);
					}
				}
			}
			
			//修改上级组织时，不允许将组织机构移动到自己的子类组织中
			List<Map<String,Object>> ancestorList = orgMapper.getAncestorOrganization(org.getParentOrgId()+"");
			for (Map<String, Object> map : ancestorList) {
				long orgId = (Long) map.get("orgId");
				if(orgId==org.getOrgId()) {
					//日志记录  sys 组织架构模块  sys-101 组织架构修改
					SysLog log = new SysLog(userNo, "1","sys", "sys-101", "9", "不允许将组织机构移动到自己的子类组织中, "+user.getLoginName()+"修改组织架构失败[orgId="+org.getOrgId()+"]！", new Date());
					return ResultUtil.retLog(202,"不允许将组织机构移动到自己的子类组织中！",log);
				}
			}

			//修改上级组织时，不允许将组织机构移动到根目录，新的组织层级如果超过5层就不允许变更
			QueryWrapper<SysOrganization> getParentOrgWp = new QueryWrapper<>();
			getParentOrgWp.eq("state", "1");
			getParentOrgWp.eq("org_id", org.getParentOrgId());
			SysOrganization parentOrg = orgMapper.selectOne(getParentOrgWp);
			if(parentOrg==null) {
				throw new Exception("updateSysOrganization->orgMapper.selectOne 查询失败");
			}else {
				int parentOrgLevel = Integer.parseInt(parentOrg.getOrgLevel());
				int count = orgMapper.countAllOrganizationLevel(org.getOrgId()+"");
//				if(parentOrgLevel==0) {
//					//日志记录  sys 组织架构模块  sys-101 组织架构修改
//					SysLog log = new SysLog(userNo, "1","sys", "sys-101", "9", "不允许将组织机构移动到根目录, "+user.getLoginName()+"修改组织架构失败[orgId="+org.getOrgId()+"]！", new Date());
//					return ResultUtil.retLog(203,"不允许将组织机构移动到根目录！",log);
//				}
				if(parentOrgLevel+count>5) {
					//日志记录  sys 组织架构模块  sys-101 组织架构修改
					SysLog log = new SysLog(userNo, "1","sys", "sys-101", "9", "修改上级组织后，新的组织层级不允许超过5层, "+user.getLoginName()+"修改组织架构失败[orgId="+org.getOrgId()+"]！", new Date());
					return ResultUtil.retLog(204,"修改上级组织后，新的组织层级不允许超过5层！",log);
				}
			}
			
			String level = parentOrg.getOrgLevel();
			String curLevel = Long.parseLong(level)+1+"";
			//计算现在组织变动后的层级差
			long levelDiff = Long.parseLong(curLevel)-Long.parseLong(oldOrg.getOrgLevel());
			oldOrg.setOrgName(org.getOrgName());
			oldOrg.setParentOrgId(org.getParentOrgId());
			oldOrg.setType(org.getType());
			oldOrg.setOrgAddress(org.getOrgAddress());
			oldOrg.setIsAdminInstitute(org.getIsAdminInstitute());
			oldOrg.setRank(0l);
			oldOrg.setOrgLevel(curLevel);
			oldOrg.setUpdateBy((long)userNo);
			oldOrg.setUpdateTime(new Date());
			orgMapper.updateById(oldOrg);
			//修改变动过的组织机构路径
			oldOrg.setOrgPath(orgMapper.getOrgPath(oldOrg.getOrgId()));
			oldOrg.setOrgPathCode(orgMapper.getOrgPathCode(oldOrg.getOrgId()));
			orgMapper.updateById(oldOrg);
			
			
			//修改上级组织后，更新现在组织的下层层级
			List<Map<String,Object>> list = orgMapper.getAllOrganization(oldOrg.getOrgId()+"");
			for (Map<String, Object> map : list) {
				long tmpOrgId = (Long) map.get("orgId");
				if(tmpOrgId==oldOrg.getOrgId()) {
					continue;
				}
				QueryWrapper<SysOrganization> tmpOrgWp = new QueryWrapper<>();
				tmpOrgWp.eq("state", "1");
				tmpOrgWp.eq("org_id", tmpOrgId);	
				SysOrganization tmpOrg = orgMapper.selectOne(tmpOrgWp);
				if(tmpOrg==null) {
					throw new Exception("updateSysOrganization->orgMapper.selectOne 查询失败");
				}else {
					long tmpLevel = Long.parseLong(tmpOrg.getOrgLevel())+levelDiff;
					tmpOrg.setOrgLevel(tmpLevel+"");
					tmpOrg.setOrgPath(orgMapper.getOrgPath(tmpOrg.getOrgId()));
					orgMapper.updateById(tmpOrg);
				}
			}			
			
			//判断原先父组织是否还存在子组织，不存在时，将isChildExist改为0，修改现在父组织的isChildExist改为1
			QueryWrapper<SysOrganization> countOldParentWp = new QueryWrapper<>();
			countOldParentWp.eq("state", "1");
			countOldParentWp.eq("parent_org_id", oldOrgParentId);	
			int oldParentCount = orgMapper.selectCount(countOldParentWp);
			if(oldParentCount==0) {
				QueryWrapper<SysOrganization> getOldParentWp = new QueryWrapper<>();
				getOldParentWp.eq("state", "1");
				getOldParentWp.eq("org_id", oldOrgParentId);
				SysOrganization oldParentOrg = orgMapper.selectOne(getOldParentWp);
				if(oldParentOrg!=null) {
					oldParentOrg.setIsChildExist("0");
					orgMapper.updateById(oldParentOrg);
				}
			}
			SysOrganization oldParentOrg2 = orgMapper.selectOne(new QueryWrapper<SysOrganization>().eq("state", "1").eq("org_id", oldOrg.getParentOrgId()));
			if(oldParentOrg2!=null) {
				oldParentOrg2.setIsChildExist("1");
				orgMapper.updateById(oldParentOrg2);
			}

			//日志记录  sys 组织架构模块  sys-101 组织架构修改
			SysLog log = new SysLog(userNo, "1","sys", "sys-101", "1", user.getLoginName()+"修改组织架构成功[orgId="+org.getOrgId()+"]！", new Date());
			return ResultUtil.retLog(200,"修改成功！",log);

		} catch (Exception e) {
			e.printStackTrace();
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();     
			throw new Exception(e.toString());
		}
	}

	@Override
	public List<Map<String, Object>> getDupGongcanAuthOrg() throws Exception {
		try {
			return orgMapper.getDupGongcanAuthOrg();
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception(e.toString());
		}
	}


}
